/**
 * Title: SingletonFactory.java
 * Description:
 * Copyright: Copyright (c) 2008
 * Company:深圳彩讯科技有限公司
 * Author 罗旭东 (hi@luoxudong.com)
 * Date 2013-8-2 下午3:58:10
 * Version 1.0 
 */
package com.luoxudong.phonenumber.service.base; 	

import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.luoxudong.phonenumber.service.database.manager.DaoManager;
import com.luoxudong.phonenumber.service.exception.PhoneNumberException;

/** 
 * ClassName: SingletonFactory 
 * Description:单例管理工厂类 
 * Create by 罗旭东
 * Date 2013-8-2 下午3:58:10 
 */
public class SingletonFactory {
	/**
	 * 缓存普通对象列表
	 */
	private static Map<String, Object> objectCache = Collections.synchronizedMap(new HashMap<String, Object>());
	
	/**
	 * 缓存数据库对象列表
	 */
	private static Map<String, DaoManager> databaseManagerCache = Collections.synchronizedMap(new HashMap<String, DaoManager>());

	
	/**
	 * 
	 * getInstance
	 * 新创建一个普通对象,并放入对象列表中
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getInstance(Class<T> clazz)
	{
		T result = null;
		synchronized(SingletonFactory.class)
		{
			if (objectCache == null)
			{
				objectCache = Collections.synchronizedMap(new HashMap<String, Object>());
			}
			
		}
		synchronized (objectCache)
		{
			result = (T) objectCache.get(clazz.getName());
			if (result == null)
			{
				result = createInstance(clazz);
				objectCache.put(clazz.getName(), result);
			}
		}
		
		return result;
	}
	
	/**
	 * 
	 * getDatabaseManagerInstance
	 *  创建一个数据库对象，并放入数据库对象列表中
	 */
	public static DaoManager getDatabaseManagerInstance(String path)
	{
		DaoManager result = null;
		synchronized (SingletonFactory.class)
		{
			if (databaseManagerCache == null)
			{
				databaseManagerCache = Collections.synchronizedMap(new HashMap<String, DaoManager>());
			}
			
		}
		synchronized (databaseManagerCache)
		{
			result = databaseManagerCache.get(path);
			if (result == null)
			{
				result = createInstance(DaoManager.class,new Class[]{String.class},new Object[]{path});
				databaseManagerCache.put(path, result);
			}
		}
		return result;

	}
	
	/**
	 * 利用反射创建对象,构造函数无参数
	 * 
	 * @param clazz
	 * @return
	 */
	private static <T> T createInstance(Class<T> clazz)
	{
		try
		{
			T result = clazz.newInstance();
			return result;
		}
		catch (InstantiationException e)
		{
			throw new PhoneNumberException("创建对象实例失败!", e);
		}
		catch (IllegalAccessException e)
		{
			throw new PhoneNumberException("创建对象实例失败!", e);
		}

	}
	
	/**
	 * 利用反射创建对象,构造函数带参数
	 * 
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private static <T> T createInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] paramValues)
	{
		
		try
		{
			Constructor<?> constructor = clazz.getConstructor(parameterTypes);//获取构造函数
			
			T result = (T) constructor.newInstance(paramValues);//构造函数参数
			return result;
		}
		catch (InstantiationException e)
		{
			throw new PhoneNumberException("创建对象实例失败!", e);
		}
		catch (Exception e)
		{
			throw new PhoneNumberException("创建对象实例失败!", e);
		}

	}
	
	/**
	 * 释放单例对象缓存
	 */
	public static void releaseCache()
	{
		//释放数据库对象
		if (databaseManagerCache != null)
		{
			synchronized (databaseManagerCache)
			{
				for(String key:databaseManagerCache.keySet())
				{
					DaoManager daoManager = databaseManagerCache.get(key);
					daoManager.closeDatabase();
					//daoManager = null;
				}
				databaseManagerCache.clear();
			}
		}
		
		//释放普通类对象
		if (objectCache != null)
		{
			objectCache.clear();
		}
		
	}
	
	@Override
	protected void finalize() throws Throwable {
		releaseCache();
		super.finalize();
	}
}
